package ex106;

public class MyInteger {
    public static final int HEX = 4; // 每个16进制 4个bit
    public static final int OCT = 3; // 每个 8进制 3个bit
    public static final int BIN = 1; // 每个 2进制 1个bit

    static final char[] digits = {
            '0', '1', '2', '3', '4', '5',
            '6', '7', '8', '9', 'A', 'B',
            'C', 'D', 'E', 'F'
    }; // 2、8、16进制需要的符号

    /**
     * @param value int
     * @param full  是否保留前面的0
     * @return 整数对应的16进制的字符串形式
     */
    public String toHexString(int value, boolean full) {
        return buildString(value, HEX, full);
    }

    /**
     * @param value int
     * @param full  是否保留前面的0
     * @return 整数对应的8进制的字符串形式
     */
    public String toOctString(int value, boolean full) {
        return buildString(value, OCT, full);
    }

    /**
     * @param value int
     * @param full  是否保留前面的0
     * @return 整数对应的2进制的字符串形式
     */
    public String toBinString(int value, boolean full) {
        return buildString(value, BIN, full);
    }

    /**
     * 把整数转换为对应进制的字节数组
     * 16进制，每4位二进制bit构成一个字节，数组共8个字节
     * 8进制，每3位二进制bit构成一个字节，数组共11个字节
     * 2进制，每1位二进制bit构成一个字节，数组共32个字节
     *
     * @param value 需要转换的整数
     * @param radix 转换的目标进制，HEX、OCT、BIN
     * @return byte[]
     */
    private byte[] formatUnsignedInteger(int value, int radix) {
        int len = 32 / radix * radix == 32 ? 32 / radix : 32 / radix + 1;
        byte[] result = new byte[len];
        int charPos = len - 1;
        int mask = (1 << radix) - 1;
        while (charPos >= 0) {
            result[charPos] = (byte) (value & mask);
            value >>>= radix;
            charPos--;
        }
        return result;
    }

    private char[] bin2char(byte[] bytes) {
        char[] result = new char[bytes.length];
        for (int i = 0; i < result.length; i++) {
            result[i] = digits[bytes[i]];
        }
        return result;
    }

    private String buildString(int value, int radix, boolean full) {
        char[] array = bin2char(formatUnsignedInteger(value, radix));
        String result = "";
        for (char c : array) {
            if (full) {
                result += c;
            } else {
                if (!("".equals(result) && c == '0')) {
                    result += c;
                }
            }
        }
        result = "".equals(result) ? "0" : result;
        return result;
    }

}
